<?php

/*
 * @todo  Create javadoc comments for remaining methods
 */

defined('__MAPEXEC__') or die('No direct access allowed');

/**
 * Manages a set of geographic points and related data for a client side interactive map.
 */
class Maps_Map_Common {

  private $coords = null;
  private $directions = true;
  private $infoWindows = true;
  private $layerControls = array();
  public $lines = null;
  private $mapId = '';
  private $navigation = array();
  private $optimalZoom = true;
  public $pois = null;
  public $polygons = null;
  private $zoomLevel = 11;
  
  public $lang = null;
  public $legend = null;

  /**
   * Class constructor
   * @param double $centerLat Latitude of map center
   * @param double $centerLng Longitude of map center
   * @param string $mapId Id of this map.
   * @return void
   */
  public function __construct($coords=null, $mapId='') {
  	if ( !empty($coords) ) {
      $this->setCenter($coords);
    }
    $this->setId($mapId);
    $this->initLang();
    $this->legend = new Maps_Map_Legend();
    $this->lines = new Maps_Map_PolyLineManager();
    $this->pois = new Maps_Map_POIManager();
    $this->polygons = new Maps_Map_PolygonManager();
  }

  /**
   * Adds a layer control to this map.
   * @param string $type Layer control type.
   * @return void
   */
  public function addLayerControl($type='') {
  	if ( !$this->layerControlExists($type) ) {
  		$this->layerControls[] = $type;
  	}
  }
  
  /**
   * Adds a navigation contorl to the map.
   * @param   String  Navigation type. Anything can be added. Exporter will handle unsupported types.
   */
  public function addNavigation($type='') {
  	if ( !$this->navigationExists($type) ) {
  		$this->navigation[] = $type;
  	}
  }
  
  /**
   * Detects whether or not driving directions are enabled.
   * @param   void
   * @return  void
   */
  public function directionsEnabled() {
    return $this->directions;
  }
  
  /**
   * Disable driving directions for this map.
   * @param   void
   * @return  void
   */
  public function disableDirections() {
    $this->directions = false;
  }
  
  /**
   * Disable automatically zooming to the optimal level.
   * @param   void
   * @return  void
   */
  public function disableOptimalZoom() {
    $this->optimalZoom = false;
  }
  
  /**
   * Enable driving directions for this map.
   * @param   void
   * @return  void
   */
  public function enableDirections() {
    $this->directions = true;
  }
  
  /**
   * Enables zooming to the optimal level.
   * @param   void
   * @return  void
   */
  public function enableOptimalZoom() {
    $this->optimalZoom = true;
  }
  
  /**
   * Gets the map center latitude.
   * @param   void
   * @return  Float   Degrees latitude
   */
  public function getCenterLat() {
    return $this->coords->getLat();
  }
  
  /**
   * Gets the map center longitude
   * @param   void
   * @return  Float   Degrees longitude
   */
  public function getCenterLng() {
    return $this->coords->getLng();
  }
  
  /**
   * Gets the latitude/longitude object for the map center.
   * @param   void
   * @return  Maps_LatLng   Latitude and longitude object
   */
  public function getLatLng() {
    return $this->coords;
  }
  
  /**
   * Returns the list of layer controls.
   * @param   void
   * @return  Array   Layer controls for this map
   */
  public function getLayerControls() {
  	return $this->layerControls;
  }
  
  /**
   * Gets the map Id, used predominently in HTML export types.
   * @param   void
   * @return  String  Map Id
   */
  public function getId() {
  	return $this->mapId;
  }
  
  /**
   * Gets the map navigation controls
   * @param   void
   * @return  Array   Navigation controls added to this map
   */
  public function getNavigationControls() {
  	return $this->navigation;
  }
  
  /**
   * Gets the maximum latitude and longitude boundries of all the
   * Points Of Interest for this map.
   * @param   void
   * @return  array   Array containing min and max lat/lng objects
   */
  public function getPOIBounds() {
    $bounds = null;
    $poi = null;
    $lat = null;
    $lng = null;
    
    if ( empty($pois) || $this->POICount < 2 ) {
      return $bounds;
    }
    
    while ($poi = $this->pois->next()) {
      $lat = $poi->getLat();
      $lng = $poi->getLng();
      
      if ($index == 0) {
        $bounds['min'] = new Maps_LatLng($lat, $lng);
        $bounds['max'] = new Maps_LatLng($lat, $lng);
      }
      
      if ($lat < $bounds['min']->getLat()) {
        $bounds['min']->setLat($lat);
      } elseif ($lat > $bounds['max']->getLat()) {
        $bounds['max']->setLat($lat);
      }
      
      if ($lng < $bounds['min']->getLng()) {
        $bounds['min']->setLng($lng);
      } elseif ($lng > $bounds['max']->getLng()) {
        $bounds['max']->setLng($lng);
      }
    }
    
    return $bounds;
  }
  
  /**
   * Return the number of Points of Interest added to this map.
   * @param   void
   * @return  Integer   Number of Points of Interest
   */
  public function getPOICount() {
  	return $this->pois->getCount();
  }
  
  /**
   * Gets the default zoom level for this map.
   * @param   void
   * @return  Integer   Zoom level
   */
  public function getZoomLevel() {
    return $this->zoomLevel;
  }
  
  /**
   * Initializes the language pack for this map.
   * @param   void
   * @return  void
   */
  private function initLang() {
    if ( isset($this->lang) ) {
      return;
    }
    
    $this->lang = new Maps_Config();
    $this->lang->set('dir_form_to', 'To');
    $this->lang->set('dir_form_from', 'From');
    $this->lang->set('dir_form_intro', 'Get directions:');
    $this->lang->set('dir_form_button', 'Go');
    $this->lang->set('dir_form_label_end', 'End address:');
    $this->lang->set('dir_form_label_start', 'Start address:');
    $this->lang->set('dir_form_head_to', 'Get directions to here:');
    $this->lang->set('dir_form_head_from', 'Get directions from here:');
    $this->lang->set('dir_link_directions', 'Directions: ');
    $this->lang->set('dir_link_from', 'from here');
    $this->lang->set('dir_link_to', 'to here');
    $this->lang->set('tab_about', 'About');
    $this->lang->set('tab_directions', 'Directions');
  }
  
  /**
   * Detects if a layer control has been previously added to this map.
   * @param   String  Layer control type
   * @return  Bool    True if exists
   */
  private function layerControlExists($type) {
    return in_array($type, $this->layerControls);
  }
  
  /**
   * Detects if a navigation control has been previously added to this map.
   * @param   String  Navigation control type
   * @return  Bool    True if navigation control exists
   */
  private function navigationExists($type) {
    return in_array($type, $this->navigation);
  }
  
  /**
   * Detects if the "optimal zoom" feature is enabled on this map.
   * @param   void
   * @return  Boolean   True if enabled
   */
  public function optimalZoomEnabled() {
    return $this->optimalZoom;
  }
  
  /**
   * Sets the map center.
   * @param   Maps_LatLng   Latitude/longitude object
   * @return  void
   */
  public function setCenter(Maps_LatLng $coords) {
    if ( empty($coords) ) {
      return;
    }
  	$this->coords = $coords;
  }

  /**
   * Sets the map Id
   * @param string $mapId Id of this map, usefull for exporting in HTML.
   * @return void
   */
  public function setId($mapId) {
  	if ( !empty($mapId) ) {
  		$this->mapId = (string) $mapId;
  	}
  }
  
  /**
   * Sets the default zoom level for this map.
   * @param   Integer   Zoom level
   * @return  void
   */
  public function setZoomLevel($level) {
    $this->zoomLevel = (integer) $level;
  }

}

?>
